package com.mf.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mf.constant.ConstantBasic;
import com.mf.entity.req.ReqRelevancyById;
import com.mf.exception.GraceException;
import com.mf.service.ServiceIncoming;
import com.mf.utils.UtilEnumNextProcess;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import com.mf.entity.dto.DtoIncomingDetail;
import com.mf.entity.req.search.SearchReqIncomingDetail;
import com.mf.mapper.MapperIncomingDetail;
import com.mf.service.ServiceIncomingDetail;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


@Service
public class ImplServiceIncomingDetail extends ServiceImpl<MapperIncomingDetail, DtoIncomingDetail> implements ServiceIncomingDetail {
    @Resource
    private ServiceIncoming serviceIncoming;

    /**
     * 参数查询条件
     */
    @Override
    public LambdaQueryWrapper<DtoIncomingDetail> fillParams(SearchReqIncomingDetail params) {
        LambdaQueryWrapper<DtoIncomingDetail> wrapper = loadQw();
        if (StringUtils.isNotEmpty(params.getKey())) {
            wrapper.and(w -> {
                w.like(DtoIncomingDetail::getMaterialInfo, params.getKey())
                        .or()
                        .like(DtoIncomingDetail::getCustomerName, params.getKey())
                        .or()
                        .like(DtoIncomingDetail::getReceiveCode, params.getKey());
            });
        }
        wrapper.eq(ObjectUtils.isNotEmpty(params.getReceiveId()), DtoIncomingDetail::getReceiveId,
                        params.getReceiveId())
                .eq(ObjectUtils.isNotEmpty(params.getCustomerId()), DtoIncomingDetail::getCustomerId,
                        params.getCustomerId())
                .eq(StringUtils.isNotBlank(params.getPackageType()), DtoIncomingDetail::getPackageType,
                        params.getPackageType())
                .eq(StringUtils.isNotBlank(params.getWarehouse()), DtoIncomingDetail::getWarehouse,
                        params.getWarehouse())
                .eq(ObjectUtils.isNotEmpty(params.getRelevancyId()),DtoIncomingDetail::getRelevancyId, params.getRelevancyId());
        return wrapper;
    }

    /**
     * 根据来料单id查询来料单详情
     */
    @Override
    public List<DtoIncomingDetail> findByIncomingId(Integer incomingId) {
        LambdaQueryWrapper<DtoIncomingDetail> wrapper = loadQw();
        wrapper.eq(DtoIncomingDetail::getReceiveId, incomingId)
                .eq(DtoIncomingDetail::getRelevancyId, ConstantBasic.NO_RELEVANCY);
        return list(wrapper);
    }

    /**
     * 根据来料id删除来料单详情
     */
    @Override
    @Transactional
    public void deleteByIncomingId(Integer incomingId) {
        LambdaQueryWrapper<DtoIncomingDetail> wrapper = loadQw();
        wrapper.eq(DtoIncomingDetail::getReceiveId, incomingId);
        remove(wrapper);
    }

    /**
     * 根据来料id查询来料单详情数量
     */
    @Override
    public Long findByIncomingIdCount(Integer incomingId) {
        LambdaQueryWrapper<DtoIncomingDetail> wrapper = loadQw();
        wrapper.eq(DtoIncomingDetail::getReceiveId, incomingId);
        return count(wrapper);
    }

    /**
     * 根据 来料单id，来料明细id清除关联信息
     */
    @Override
    @Transactional
    public void deleteRelevancyById(Integer incomingId, Integer id) {
        final DtoIncomingDetail dtoIncomingDetail = new DtoIncomingDetail();
        dtoIncomingDetail.setId(id);
        dtoIncomingDetail.setRelevancyId(ConstantBasic.NO_RELEVANCY);
        dtoIncomingDetail.setReceiveId(incomingId);
        dtoIncomingDetail.setRelevancyType(ConstantBasic.NO_RELEVANCY);
        updateById(dtoIncomingDetail);
    }

    /**
     * 根据关联id,类型查询 对应的关联来料单明细
     */
    @Override
    public List<Integer> listByRelevancyId(Integer relevancyId, Integer type) {
        final LambdaQueryWrapper<DtoIncomingDetail> wrapper = loadQw();
        wrapper.eq(DtoIncomingDetail::getRelevancyId, relevancyId)
                .eq(DtoIncomingDetail::getRelevancyType, type);
        final List<DtoIncomingDetail> list = this.list(wrapper);
        return list.stream().map(DtoIncomingDetail::getReceiveId).distinct().toList();
    }
    /**
     * 根据源id，类型查询对应map集合
     */
    @Override
    public Map<Integer, DtoIncomingDetail> getDtoIncomingDetailMap(Integer sourceId, Integer workSource) {
        SearchReqIncomingDetail params = SearchReqIncomingDetail.builder()
                .receiveId(sourceId)
                .warehouse(UtilEnumNextProcess.getNextProcess(workSource))
                .relevancyId(ConstantBasic.NO_RELEVANCY)
                .build();
        List<DtoIncomingDetail> dtoIncomingDetails = this.findListByParams(params);

        // 转换为map集合用于验证
        return dtoIncomingDetails.stream().collect(Collectors.toMap(DtoIncomingDetail::getId, v -> v));
    }

    /**
     * 设置关联集合
     */
    @Override
    public void setRelevancyList(Integer sourceId, Integer id, Map<Integer, DtoIncomingDetail> detailMap, List<ReqRelevancyById> relevancyByIds) {
        if (!detailMap.containsKey(id)) {
            GraceException.display("来料明细【" + id + "】不存在");
        }

        ReqRelevancyById reqRelevancyById = new ReqRelevancyById();
        reqRelevancyById.setId(id);
        // 关联对应的分拣工单id
        reqRelevancyById.setRelevancyId(sourceId);
        relevancyByIds.add(reqRelevancyById);
    }

    /**
     * 根据id,关联id，类型设置关联信息
     * return 返回当前明细是否已全部关联完成
     */
    @Override
    @Transactional
    public void setRelevancy(List<ReqRelevancyById> reqRelevancyByIds, Integer incomingId, Integer relevancyType) {
        ArrayList<DtoIncomingDetail> details = new ArrayList<>();
        for (ReqRelevancyById reqRelevancyById : reqRelevancyByIds) {
            DtoIncomingDetail detail = new DtoIncomingDetail();
            detail.setId(reqRelevancyById.getId());
            detail.setRelevancyId(reqRelevancyById.getRelevancyId());
            detail.setRelevancyType(relevancyType);
            details.add(detail);
        }
        // 更新详情关联信息
        updateBatchById(details);

        // 查询当前明细是否全部关联完成
        final LambdaQueryWrapper<DtoIncomingDetail> wrapper = loadQw();
        wrapper.eq(DtoIncomingDetail::getReceiveId, incomingId);
        final List<DtoIncomingDetail> incomingDetails = list();


        for (DtoIncomingDetail incomingDetail : incomingDetails) {
            if (ConstantBasic.NO_RELEVANCY.equals(incomingDetail.getRelevancyId())) {
                // 没有更新完成,同步关联状态
                serviceIncoming.updateRelevancyStatus(incomingId, ConstantBasic.NO_RELEVANCY);
                return;
            }
        }

        // 全部已关联 更新来料单关联状态
        serviceIncoming.updateRelevancyStatus(incomingId, ConstantBasic.RELEVANCY_STATUS_YES);
    }
}